home *** CD-ROM | disk | FTP | other *** search
- /**
- --
- -- App: QuickDraw GX Scrolling
- --
- -- File: GX Scrolling Controls.c
- --
- --
- -- Comments: This file contains all of the code required to maintain and adjust
- -- the scroll bars attached to the window. We also update the gxMapping of
- -- our child gxViewPort as the user scrolls. This approach guarantees that
- -- all of the shapes within our GX picture are drawn in their correct locations
- -- after scrolling.
- --
- -- You can search on "GX Scrolling" to find the additions which were added to
- -- support GX scrolling.
- --
- --
- -- Version: 1.0 1/93 added general GX support & scrolling
- -- 7/95 Converted to ThinkC 6 and new GX interfaces
- --
- --
- -- Components: QD GX Scrolling main.c
- -- QD GX Scrolling main.h
- -- QD GX Scrolling Controls.c
- -- QD GX Scrolling Controls.h
- -- QD GX Scrolling.π.rsrc
- --
- --
- -- Notes: 1) Print this file in landscape for the best results
- -- 2) If you are using THINK C v5.x, I have added markers to navigate the
- -- code.
- -- 3) This code was adapted and simplyified from the "DTS AE Skeleton" sample.
- --
- --
- -- Author: Pete "Luke" Alexander
- -- Developer Technical Support
- -- AppleLink: DEVSUPPORT
- --
- --
- -- ©1992 - 1993 Apple Computer, Inc.
- -- All rights reserved.
- --
- **/
-
- #include <Windows.h>
-
- #include "QDGX Scrolling main.h"
- #include "QDGX Scrolling Controls.h"
-
- #include <GXGraphics.h>
- #include <GXMath.h>
-
- extern gxShape gthePage;
- extern gxViewPort gcontentViewPort;
-
- //
- // Internal Function Prototypes
- //
- void ResizeScrollBars(WindowPtr theWindow);
- void InvalidateScrollBars(WindowPtr theWindow);
- void DoControl(Point thePoint, ControlHandle theControl, short controlPart);
- pascal void DoControlButton(ControlHandle theControl, short controlPart);
- void DoScroll(WindowPtr theWindow, short hScroll, short vScroll);
- void AdjustScrollBar(ControlHandle theControl);
-
-
- /**----- ResizeScrollBars --------------------------------------------------------------------
- --
- -- This function is used when the window is resized. It resizes the scroll bars to match.
- --
- **/
- void ResizeScrollBars(WindowPtr theWindow)
- {
- MoveControl(((MyWindowPeek)theWindow)->vScrollBar,
- theWindow->portRect.right-(kScrollBarWidth-1),
- theWindow->portRect.top-1);
- SizeControl(((MyWindowPeek)theWindow)->vScrollBar, kScrollBarWidth,
- theWindow->portRect.bottom-theWindow->portRect.top-
- (kScrollBarWidth-3));
- MoveControl(((MyWindowPeek)theWindow)->hScrollBar,
- theWindow->portRect.left-1,
- theWindow->portRect.bottom-(kScrollBarWidth-1));
- SizeControl(((MyWindowPeek)theWindow)->hScrollBar,
- theWindow->portRect.right-theWindow->portRect.left-
- (kScrollBarWidth-3), kScrollBarWidth);
-
- AdjustScrollBar(((MyWindowPeek)theWindow)->hScrollBar);
- AdjustScrollBar(((MyWindowPeek)theWindow)->vScrollBar);
- }
-
-
-
- /**----- InvalidateScrollBars ----------------------------------------------------------------
- --
- -- This function is used to invalidate the area under the scroll bars for redrawing.
- -- The invalid area will be included in the next update event.
- --
- **/
- void InvalidateScrollBars(WindowPtr theWindow)
- {
- Rect tempRect;
-
- SetPort(theWindow);
-
- tempRect = theWindow->portRect;
- tempRect.left = tempRect.right-(kScrollBarWidth-1);
- InvalRect(&tempRect);
- EraseRect(&tempRect);
-
- tempRect = theWindow->portRect;
- tempRect.top = tempRect.bottom-(kScrollBarWidth-1);
- InvalRect(&tempRect);
- EraseRect(&tempRect);
- }
-
-
-
- /**----- DoControl ---------------------------------------------------------------------------
- --
- -- This function is used when the mouse is clicked on one of the scroll bars in a document.
- --
- **/
- void DoControl(Point thePoint, ControlHandle theControl, short controlPart)
- {
- short oldValue;
- short amountToScroll;
- WindowPtr theWindow;
-
- switch (controlPart)
- {
- case inUpButton:
- case inDownButton:
- case inPageUp:
- case inPageDown:
- TrackControl(theControl, thePoint, (ControlActionUPP)DoControlButton);
- break;
- case inThumb:
- oldValue = GetCtlValue(theControl);
- if (TrackControl(theControl, thePoint, nil));
- {
- amountToScroll = - (GetCtlValue(theControl) - oldValue);
- theWindow = (**theControl).contrlOwner;
- if (((MyWindowPeek)theWindow)->hScrollBar == theControl) /* horizontal? */
- DoScroll(theWindow, amountToScroll, 0);
- else
- DoScroll(theWindow, 0, amountToScroll);
- AdjustScrollBar(theControl);
- }
- break;
- }
- }
-
-
-
- /**----- DoControlButton ---------------------------------------------------------------------
- --
- -- This is the actionProc for the first call to TrackControl in DoControl. This routine
- -- is called by the operating system while the mouse button is being held on the UpButton,
- -- DownButton, PageUp, and PageDown areas. It updates the window and scroll bars.
- --
- **/
- pascal void DoControlButton(ControlHandle theControl, short controlPart)
- {
- WindowPtr theWindow;
- long percent;
- long direction;
- short amountToScroll;
- short theMax, theValue;
-
- switch (controlPart)
- {
- case inUpButton:
- percent = 15;
- direction = 1;
- break;
- case inDownButton:
- percent = 15;
- direction = -1;
- break;
- case inPageUp:
- percent = 90;
- direction = 1;
- break;
- case inPageDown:
- percent = 90;
- direction = -1;
- break;
- default:
- return; /* IMPORTANT: controlPart will often be zero - take no action! */
- }
-
- theWindow = (**theControl).contrlOwner;
-
- if (theControl == ((MyWindowPeek)theWindow)->hScrollBar) /* Horizontal */
- amountToScroll = (short)((long)(theWindow->portRect.right -
- theWindow->portRect.left -
- (kScrollBarWidth-1)) *
- percent/100 * direction);
- else /* Vertical */
- amountToScroll = (short)((long)(theWindow->portRect.bottom -
- theWindow->portRect.top -
- (kScrollBarWidth-1)) *
- percent/100 * direction);
-
- theValue = GetCtlValue(theControl);
- theMax = GetCtlMax(theControl);
-
- /* Don't allow scrolling past limits */
- if (amountToScroll < 0) /* scrolling right or down */
- {
- if ((theValue + -amountToScroll) > theMax)
- amountToScroll = - (theMax - theValue);
- }
- else /* scrolling left or up */
- {
- if ((theValue + -amountToScroll) < 0)
- amountToScroll = theValue;
- }
-
- /* Scroll the contents of the window */
- if (theControl == ((MyWindowPeek)theWindow)->hScrollBar) /* Horizontal */
- DoScroll(theWindow, amountToScroll, 0);
- else /* Vertical */
- DoScroll(theWindow, 0, amountToScroll);
-
- AdjustScrollBar(theControl);
- }
-
-
-
- /**----- DoScroll ----------------------------------------------------------------------------
- --
- -- This procedure scrolls the contents of a document window an amount specified in
- -- hScroll and vScroll, and fills the empty space created. We also adjust the gxMapping
- -- of our child gxViewPort - "gcontentViewPort". This ensures that all of our shapes
- -- are drawn in the correct location after the scrolling.
- --
- **/
- void DoScroll(WindowPtr theWindow, short hScroll, short vScroll)
- {
- Rect scrollRect;
- Point scrollPt;
- RgnHandle myRgn;
- gxMapping viewPortMapping;
-
- if ((hScroll == 0) && (vScroll == 0)) return;
-
- //
- // The user has scrolled the contents of the window, therefore we need
- // to update the mapping of the "gcontentViewPort" to reflect this change.
- // If we did not adjust the mapping or transform of all of our shape(s) on
- // the page, they would be redrawn in their original unscrolled location
- // because the geometry of each gxShape has not been changed.
- //
- // We get the mapping of "gcontentViewPort", and adjust the mapping for the
- // scroll amount. We will then reset the mapping. The "ff" macro converts
- // an integer to their fixed point equivalents. (GX Scrolling)
- //
- GXGetViewPortMapping(gcontentViewPort, &viewPortMapping);
-
- MoveMapping(&viewPortMapping, ff(hScroll), ff(vScroll));
-
- GXSetViewPortMapping(gcontentViewPort, &viewPortMapping);
-
-
- /* Scroll contents of window except for scroll bars */
- scrollRect = theWindow->portRect;
- scrollRect.right -= (kScrollBarWidth-1);
- scrollRect.bottom -= (kScrollBarWidth-1);
-
- SetPort(theWindow);
- myRgn = NewRgn();
-
- ScrollRect(&scrollRect, hScroll, vScroll, myRgn);
- SetPt(&scrollPt, hScroll, vScroll);
-
- AddPt(scrollPt, &((MyWindowPeek)theWindow)->origin);
-
- DrawWindow(theWindow);
-
- DisposeRgn(myRgn);
- }
-
-
-
- /**----- AdjustScrollBar ---------------------------------------------------------------------
- --
- -- This function looks at the current state of the window, and adjusts the maximum,
- -- minimum, and current values for both scroll bars.
- --
- **/
- void AdjustScrollBar(ControlHandle theControl)
- {
- WindowPtr theWindow;
- Rect picFrame;
- short delta1, delta2;
- short theMax;
-
- theWindow = (**theControl).contrlOwner;
- picFrame = ((MyWindowPeek)theWindow)->documentBoundsRect;
- OffsetRect(&picFrame, -picFrame.left, -picFrame.top); /* Adjust upper left to 0,0 */
-
- if (theControl == ((MyWindowPeek)theWindow)->hScrollBar) /* Horizontal scroll bar */
- {
- delta1 = - theWindow->portRect.left - ((MyWindowPeek)theWindow)->origin.h;
- delta2 = - delta1 + picFrame.right - (theWindow->portRect.right -
- theWindow->portRect.left - (kScrollBarWidth-1));
- }
- else /* Vertical scroll bar */
- {
- delta1 = - theWindow->portRect.top - ((MyWindowPeek)theWindow)->origin.v;
- delta2 = - delta1 + picFrame.bottom - (theWindow->portRect.bottom -
- theWindow->portRect.top - (kScrollBarWidth-1));
- }
-
- theMax = 0;
- if (delta1 > 0) theMax += delta1;
- if (delta2 > 0) theMax += delta2;
-
- if (theMax > 0)
- {
- SetCtlMax(theControl, theMax);
- SetCtlValue(theControl, delta1);
- }
- else
- SetCtlMax(theControl, 0);
- }